﻿using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using Microsoft.CSharp;

namespace NRemedy
{
    public class CSharpModelGenerator
    {
        private CodeGeneratorOptions _options;
        private ARSchema asrsch;


        public CSharpModelGenerator(ARLoginContext context,ARServerDefaultFactory factory)
        {
            asrsch = new ARSchema(context, factory);
            _options = new CodeGeneratorOptions();
            _options.BlankLinesBetweenMembers = false;
            _options.IndentString = "\t";
        }

        public CSharpModelGenerator(ARLoginContext context): this(context, new ARServerDefaultFactory())
        {
        }

        public CodeCompileUnit GenerateClassByFormName(string FormName, CSharpModelGeneratorDefaultFactory csmgdf)
        {
            CodeCompileUnit ccu = new CodeCompileUnit();
            CSharpModelGenerateCode cmgc = new CSharpModelGenerateCode();
            ccu = cmgc.GenerateClassByFormName(asrsch, FormName, csmgdf);
            //IGenerateNameResolver gnr = csmgdf.CreateGenerateNameResolver();
            ////root namespace
            //IGenerateRootNamespace rn = csmgdf.CreateGenerateRootNamespace();
            //rn.Create(ccu);
            ////import namespace
            //IGenerateImportNamespace imn = csmgdf.CreateGenerateImportNamespace();
            //imn.Create(ccu.Namespaces[0]);
            ////class
            //IGenerateClass gc = csmgdf.CreateGenerateClass() ;
            //IGenerateClassAttribute igca = csmgdf.CreateGenerateClassAttribute();
            //gc.Create(ccu.Namespaces[0], gnr.DefaultClassNameResolver(FormName), FormName, igca);
            ////field
            //IGetARFieldFilterDelegate affd = csmgdf.CreateGetARFieldFilterDelegate();
            //var fields = asrsch.GetListField(FormName, affd.getARFieldFilterDelegate());
            //IGetGenerateFieldDelegate igfd = csmgdf.CreateGenerateFieldDelegate();
            //GenerateFieldDelegate gfd = igfd.getGenerateFieldDelegate();
            //foreach (var f1 in fields)
            //{
            //    IGenerateFieldFactory igff = csmgdf.CreateGenerateFieldFactory();
            //    IGenerateField igf = igff.getGenerateFieldCreate((ARType)f1.DataType);
            //    igf.Create(ccu.Namespaces[0].Types[0], gnr.DefaultFieldNameResolver(f1.Name), ARTypeConvert.MappingARType(f1.DataType).Name, gnr.DefaultPropertyNameResolver(f1.Name), gfd);
            //}
            ////property
            //Dictionary<string, object> mapping = new Dictionary<string, object>();
            //IGetGeneratePropertyDelegate igpd = csmgdf.CreateGeneratePropertyDelegate();
            //GeneratePropertyDelegate gpd = igpd.getGeneratePropertyDelegate();
            //IGeneratePropertyAttribute igpa = csmgdf.CreateGeneratePropertyAttribute();
            //foreach (var f2 in fields)
            //{
            //    mapping.Clear();
            //    mapping.Add("DatabaseID", f2.Id);
            //    mapping.Add("DatabaseName", f2.Name);
            //    mapping.Add("DataType", (ARType)f2.DataType);
            //    BMC.ARSystem.Limit limit = f2.Limit;
            //    IGeneratePropertyFactory igpf = csmgdf.CreateGeneratePropertyFactory();
            //    IGenerateProperty igp = igpf.getGeneratePropertyCreate((ARType)f2.DataType);
            //    igp.Create(ccu.Namespaces[0].Types[0], gnr.DefaultPropertyNameResolver(f2.Name), ARTypeConvert.MappingARType(f2.DataType).Name, limit, mapping, gpd, igpa);
            //}
            return ccu;
        }

        public string GenerateCodeByCodeCompileUnit(CodeCompileUnit ccu)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            StringWriter sw = new StringWriter();
            string code = string.Empty;
            try
            {
                provider.GenerateCodeFromCompileUnit(ccu, sw, _options);
                sw.Flush();
                code = sw.GetStringBuilder().ToString();
                return code;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                sw.Close();
            }
        }

      
    }
}
